home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Server⁄Tracker 4.0 / player.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-01  |  10.5 KB  |  444 lines  |  [TEXT/KAHL]

  1. /* player.c */
  2.  
  3. /* $Id: player.c,v 4.0 1994/01/11 17:51:40 espie Exp espie $
  4.  * $Log: player.c,v $
  5.  * Revision 4.0  1994/01/11  17:51:40  espie
  6.  * Use the new UI calls.
  7.  * Use the new pref settings.
  8.  *
  9.  * Revision 1.14  1994/01/09  23:24:37  Espie
  10.  * Last bug fix.
  11.  *
  12.  * Revision 1.13  1994/01/09  17:36:22  Espie
  13.  * Generalized open.c.
  14.  *
  15.  * Revision 1.12  1994/01/08  03:55:43  Espie
  16.  * Suppressed really outdated code.
  17.  * New names: new_channel_tag_list, release_audio_channel.
  18.  *
  19.  * Revision 1.11  1994/01/08  02:04:21  Espie
  20.  * Some notice to status.
  21.  *
  22.  * Revision 1.10  1994/01/07  15:06:26  Espie
  23.  * *** empty log message ***
  24.  *
  25.  * Revision 1.9  1994/01/06  22:32:42  Espie
  26.  * Use new pref scheme.
  27.  *
  28.  * Revision 1.8  1994/01/05  16:10:49  Espie
  29.  * *** empty log message ***
  30.  *
  31.  * Revision 1.7  1994/01/05  14:54:09  Espie
  32.  * *** empty log message ***
  33.  *
  34.  * Revision 1.6  1994/01/05  13:50:43  Espie
  35.  * Use get_ui
  36.  *
  37.  * Revision 1.5  1994/01/05  01:59:14  Espie
  38.  * Added prototypes.
  39.  *
  40.  * Revision 1.4  1993/12/28  13:54:44  Espie
  41.  * Use autoinit feature of display.c
  42.  *
  43.  * Revision 1.3  1993/12/27  02:35:02  Espie
  44.  * discard_buffer forgotten...
  45.  *
  46.  * Revision 1.2  1993/12/26  18:54:21  Espie
  47.  * Handle errors better.
  48.  *
  49.  * Revision 1.1  1993/12/26  00:55:53  Espie
  50.  * Initial revision
  51.  *
  52.  * Revision 3.18  1993/12/04  16:12:50  espie
  53.  * Lots of changes.
  54.  *
  55.  * Revision 3.17  1993/11/19  14:27:06  espie
  56.  * Stupid bug.
  57.  *
  58.  * Revision 3.16  1993/11/17  15:31:16  espie
  59.  * New high-level functions.
  60.  *
  61.  * Revision 3.15  1993/11/11  20:00:03  espie
  62.  * Amiga support.
  63.  *
  64.  * Revision 3.14  1993/08/04  11:34:33  espie
  65.  * *** empty log message ***
  66.  *
  67.  * Revision 3.13  1993/07/18  11:49:29  espie
  68.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  69.  *
  70.  * Revision 3.12  1993/07/18  10:39:44  espie
  71.  * Added forking under unix.
  72.  *
  73.  *
  74.  * Revision 3.10  1993/05/09  14:06:03  espie
  75.  * Reniced verbose output display.
  76.  *
  77.  * Revision 3.9  1993/04/25  14:08:15  espie
  78.  * Bug fix: now use correct finetune when loading samples/starting notes.
  79.  *
  80.  * Revision 3.8  1993/01/15  14:00:28  espie
  81.  * Added bg/fg test.
  82.  *
  83.  * Revision 3.6  1992/11/27  10:29:00  espie
  84.  * General cleanup
  85.  *
  86.  * Revision 3.5  1992/11/24  10:51:19  espie
  87.  * un#ifdef'ed showseq code.
  88.  *
  89.  * Revision 3.3  1992/11/22  17:20:01  espie
  90.  * Added <> operators.
  91.  * Added update frequency on the fly.
  92.  *
  93.  * Revision 3.2  1992/11/20  14:53:32  espie
  94.  * Added finetune.
  95.  *
  96.  * Revision 3.1  1992/11/19  20:44:47  espie
  97.  * Protracker commands.
  98.  *
  99.  * Revision 3.0  1992/11/18  16:08:05  espie
  100.  * New release.
  101.  *
  102.  * Revision 2.19  1992/11/17  17:15:37  espie
  103.  * Added interface using may_getchar(). Still primitive, though.
  104.  * imask, start.
  105.  * Added transpose feature.
  106.  * Added possibility to get back to MONO for the sgi.
  107.  * Added stereo capabilities to the indigo version.
  108.  * Added two level of fault tolerancy.
  109.  * Added some control on the number of replays,
  110.  * and better error recovery.
  111.  */
  112.      
  113. #include <stdio.h>
  114.      
  115. #include "defs.h"
  116. #include "song.h"
  117. #include "channel.h"
  118. #include "extern.h"
  119. #include "tags.h"
  120. #include "prefs.h"
  121.      
  122.  
  123. ID("$Id: player.c,v 4.0 1994/01/11 17:51:40 espie Exp espie $")
  124.      
  125.  
  126. /* setting up a given note */
  127.  
  128. void reset_note(ch, note, pitch)
  129. struct channel *ch;
  130. int note;
  131. int pitch;
  132.    {
  133.    ch->pitch = pitch;
  134.    ch->note = note;
  135.    ch->viboffset = 0;
  136.    play_note(ch->audio, ch->samp, pitch);
  137.    }
  138.  
  139. /* changing the current pitch (value
  140.  * may be temporary, and not stored
  141.  * in channel pitch, for instance vibratos.
  142.  */
  143. void set_current_pitch(ch, pitch)
  144. struct channel *ch;
  145. int pitch;
  146.    {
  147.       /* save current pitch in case we want to change
  148.        * the step table on the run
  149.    ch->cpitch = pitch;
  150.    ch->step = step_table[pitch];
  151.       */
  152.    set_play_pitch(ch->audio, pitch);
  153.    }
  154.  
  155. /* changing the current volume. You HAVE to get through
  156.  * there so that it will work on EVERY machine.
  157.  */
  158. void set_current_volume(ch, volume)
  159. struct channel *ch;
  160. int volume;
  161.    {
  162.    ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  163.    set_play_volume(ch->audio, ch->volume);
  164.    }
  165.  
  166. void set_position(ch, pos)
  167. struct channel *ch;
  168. int pos;
  169.    {
  170.    set_play_position(ch->audio, pos);
  171.    }
  172.  
  173. /* init_channel(ch, dummy):
  174.  * setup channel, with initially
  175.  * a dummy sample ready to play,
  176.  * and no note.
  177.  */
  178. LOCAL void init_channel(ch)
  179. struct channel *ch;
  180.    {
  181.    ch->samp = NULL;
  182.    ch->finetune = 0;
  183.    ch->audio = new_channel_tag_list(TAG_END);
  184.    ch->volume = 0; 
  185.    ch->pitch = 0; 
  186.    ch->note = NO_NOTE;
  187.  
  188.       /* we don't setup arpeggio values. */
  189.    ch->viboffset = 0; 
  190.    ch->vibdepth = 0;
  191.  
  192.    ch->slide = 0; 
  193.  
  194.    ch->pitchgoal = 0; 
  195.    ch->pitchrate = 0;
  196.  
  197.    ch->volumerate = 0;
  198.  
  199.    ch->vibrate = 0;
  200.    ch->adjust = do_nothing;
  201.    }
  202.  
  203.  
  204.  
  205. LOCAL int VSYNC;          /* base number of sample to output */
  206. LOCAL void (*eval[NUMBER_EFFECTS]) P((struct automaton *a, struct channel *ch));
  207.                     /* the effect table */
  208. LOCAL int oversample;     /* oversample value */
  209. LOCAL int frequency;      /* output frequency */
  210. LOCAL int channel;        /* channel loop counter */
  211.  
  212. LOCAL struct channel chan[NUMBER_TRACKS];
  213.                     /* every channel */
  214.  
  215. LOCAL struct sample_info *voices;
  216.  
  217. LOCAL struct automaton a;
  218.  
  219.  
  220. void init_player(o, f)
  221. int o, f;
  222.    {
  223.    oversample = o;
  224.    frequency = f;
  225.    init_tables(o, f);
  226.    init_effects(eval);
  227.    }
  228.  
  229. LOCAL void setup_effect(ch, a, e)
  230. struct channel *ch;
  231. struct automaton *a;
  232. struct event *e;
  233.    {
  234.    int samp, cmd;
  235.  
  236.       /* retrieves all the parameters */
  237.    samp = e->sample_number;
  238.  
  239.       /* load new instrument */
  240.    if (samp)  
  241.       {
  242.          /* note that we can change sample in the middle
  243.           * of a note. This is a *feature*, not a bug (see
  244.           * made). Precisely: the sample change will be taken
  245.           * into account for the next note, BUT the volume change
  246.           * takes effect immediately.
  247.           */
  248.       ch->samp = voices + samp;
  249.       ch->finetune = voices[samp].finetune;
  250.       if ((1L<<samp) & get_pref_scalar(PREF_IMASK))
  251.          ch->samp = voices;
  252.       set_current_volume(ch, voices[samp].volume);
  253.       }
  254.  
  255.    a->note = e->note;
  256.    if (a->note != NO_NOTE)
  257.       a->pitch = pitch_table[a->note][ch->finetune];
  258.    else
  259.       a->pitch = e->pitch;
  260.    cmd = e->effect;
  261.    a->para = e->parameters;
  262.  
  263.    if (a->pitch >= REAL_MAX_PITCH)
  264.       {
  265.       char buffer[60];
  266.       sprintf(buffer,"Pitch out of bounds %d", a->pitch);
  267.       status(buffer);
  268.       a->pitch = 0;
  269.       error = FAULT;
  270.       }
  271.  
  272.    dump_event(ch, e);
  273.  
  274.       /* check for a new note: portamento
  275.        * is the special case where we do not restart
  276.        * the note.
  277.        */
  278.    if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  279.       reset_note(ch, a->note, a->pitch);
  280.    ch->adjust = do_nothing;
  281.       /* do effects */
  282.    (eval[cmd])(a, ch);
  283.    }
  284.  
  285.  
  286. LOCAL void adjust_sync(ofreq, tempo)
  287. int ofreq, tempo;
  288.    {
  289.    VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  290.    }
  291.  
  292. LOCAL void play_once(a)
  293. struct automaton *a;
  294.    {
  295.    int channel;
  296.  
  297.    if (a->do_stuff & DELAY_PATTERN)
  298.       for (channel = 0; channel < NUMBER_TRACKS; channel++)
  299.          /* do the effects */
  300.          (chan[channel].adjust)(chan + channel);
  301.    else
  302.       {  
  303.       if (a->counter == 0)
  304.          {
  305.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  306.             /* setup effects */
  307.             setup_effect(chan + channel, a, 
  308.                &(a->pattern->e[channel][a->note_num]));
  309.          dump_event(0, 0);
  310.          }
  311.       else
  312.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  313.             /* do the effects */
  314.             (chan[channel].adjust)(chan + channel);
  315.       }
  316.  
  317.       /* advance player for the next tick */
  318.    next_tick(a);
  319.       /* actually output samples */
  320.    resample(oversample, VSYNC / a->finespeed);
  321.    }
  322.  
  323. LOCAL struct tag pres[2];
  324.  
  325.  
  326. struct tag *play_song(song, start)
  327. struct song *song;
  328. int start;
  329.    {
  330.    int tempo;
  331.    int countdown;      /* keep playing the tune or not */
  332.  
  333.    song_title(song->title);
  334.    pres[1].type = TAG_END;
  335.    
  336.    tempo = get_pref_scalar(PREF_SPEED);
  337.  
  338.    adjust_sync(frequency, tempo);
  339.     /* a repeats of 0 is infinite replays */
  340.    
  341.    countdown = get_pref_scalar(PREF_REPEATS);
  342.    if (countdown == 0)
  343.       countdown = 50000;   /* ridiculously huge number */
  344.  
  345.    voices = song->samples; 
  346.  
  347.    init_automaton(&a, song, start);
  348.  
  349.    release_audio_channels();
  350.  
  351.    for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  352.       init_channel(chan + channel);
  353.  
  354.    while(countdown)
  355.       {
  356.       struct tag *result;
  357.       
  358.       play_once(&a);
  359.       result = get_ui();
  360.       while(result = get_tag(result))
  361.          {
  362.          switch(result->type)
  363.             {  
  364.          case UI_LOAD_SONG:
  365.             if (!result->data.pointer)
  366.                break;
  367.          case UI_NEXT_SONG:
  368.          case UI_PREVIOUS_SONG:
  369.             discard_buffer();
  370.             pres[0].type = result->type;
  371.             pres[0].data = result->data;
  372.             return pres;
  373.          case UI_QUIT:
  374.             discard_buffer();
  375.             end_all(0);
  376.             /* NOTREACHED */
  377.          case UI_SET_BPM:
  378.             tempo = result->data.scalar;
  379.             adjust_sync(frequency, tempo);
  380.             break;
  381.          case UI_RESTART:
  382.             discard_buffer();
  383.             init_automaton(&a, song, start);
  384.             release_audio_channels();
  385.             for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  386.                init_channel(chan + channel);
  387.             break;
  388.          case UI_JUMP_TO_PATTERN:
  389.             if (result->data.scalar >= 0 && result->data.scalar < a.info->length)
  390.                {
  391.                discard_buffer();
  392.                init_automaton(&a, song, result->data.scalar);
  393.                }
  394.             break;
  395.             /*
  396.          case ' ':
  397.             while (may_getchar() == EOF)
  398.                ;
  399.             break;
  400.              */
  401.          default:
  402.             break;
  403.             }
  404.          result++;
  405.          }
  406.  
  407.       {
  408.       int new_freq;
  409.       if (new_freq = update_frequency())
  410.          {
  411.          frequency = new_freq;
  412.          adjust_sync(frequency, tempo);
  413.          init_tables(oversample, frequency);
  414.          }
  415.       }
  416.  
  417.       switch(error)
  418.          {
  419.       case NONE:
  420.          break;
  421.       case ENDED:
  422.          countdown--;
  423.          break;
  424.       case SAMPLE_FAULT:
  425.       case FAULT:
  426.       case PREVIOUS_SONG:
  427.       case NEXT_SONG:
  428.       case UNRECOVERABLE:
  429.          if ( (error == SAMPLE_FAULT && get_pref_scalar(PREF_TOLERATE))
  430.             ||(error == FAULT && get_pref_scalar(PREF_TOLERATE) > 1) )
  431.             break;
  432.          pres[0].type = PLAY_ERROR;
  433.          pres[0].data.scalar = error;
  434.          return pres;
  435.       default:
  436.          break;
  437.          }
  438.          error = NONE;
  439.       }
  440.    pres[0].type = TAG_IGNORE;      
  441.    return pres;
  442.    }
  443.  
  444.